#include <graphics.h>
#include <math.h>
#include <stdio.h>
#include <conio.h>
#define PI 3.14159265358979323846
using namespace std;


void draw_gradient_circle(int cx, int cy, int radius) 
{
	int centerX = cx;
	int centerY = cy;
	radius = (int)radius * 0.95;
	
	for (int y = 0; y < 600; y++) 
	{
		for (int x = 0; x < 800; x++) 
		{
			float dx = x - centerX;
			float dy = y - centerY;
			float dist = sqrt(dx*dx + dy*dy);  // 点到圆心的径向距离
			if (dist > radius) continue;       // 点在圆外，跳过			
			float t = dist / radius;           // 渐变比例（0=中心，1=边缘）
			t = pow(t, 3);                   // 非线性渐变，边缘变黑加速			
			color_t currentColor;
			if (y <= 300) 
			{  // 上半部分：天蓝色 + 四周变黑
				// 蓝色基础色：RGB(63, 83, 130)
				int r = (int)(63 * (1 - t));
				int g = (int)(83 * (1 - t));  // 绿色通道随距离增加而减少
				int b = (int)(130 * (1 - t));  // 蓝色通道随距离增加而减少
				currentColor = EGERGB(r, g, b);   // 边缘混合黑色（g和b减少）
			} 
			else 
			{  // 下半部分：棕色 + 四周变黑
				// 棕色基础色：RGB(85, 78, 54)
				int r = (int)(85 * (1 - t));
				int g = (int)(78 * (1 - t));// 绿色通道随距离增加而减少
				int b = (int)(54 * (1 - t));
				currentColor = EGERGB(r, g, b);   //边缘变深（g减少）
			}			
			putpixel(x, y, currentColor);
		}
	}	
}

// 双色椭圆结构体
typedef struct 
{
	float x, y;         // 中心坐标
	float a, b;         // 长/短半轴
	float angle;        // 旋转弧度
	color_t top_color;        // 上半部颜色
	color_t bottom_color;     // 下半部颜色
} MyEllipse;


// 初始化椭圆
void initEllipse(MyEllipse* e, float x, float y, float a, float b, 
	color_t top_c, color_t bottom_c) 
{
	e->x = x;
	e->y = y;
	e->a = a;
	e->b = b;
	e->angle = 0;
	e->top_color = top_c;
	e->bottom_color = bottom_c;
}

// 绘制并填充旋转椭圆（上下不同色）
void drawEllipse(const MyEllipse* e) 
{
	// 绘制边界线时改用抗锯齿线型
//	setlinestyle(PS_SOLID | PS_ENDCAP_ROUND | PS_JOIN_ROUND, 2);
	// 创建临时图像（大小要能容纳整个仪表）
	const int imgWidth = 800;
	const int imgHeight = 600;
	PIMAGE pimg = newimage(imgWidth, imgHeight);
	
	// 设置临时图像为当前绘图目标
	settarget(pimg);	
	// 清空临时图像（透明背景）
	setbkcolor(TRANSPARENT);
	cleardevice();
	
	setcolor(WHITE);
	setfillcolor(WHITE);
	
	// 在临时图像上绘制仪表（以图像中心为原点）
	const float centerX = imgWidth / 2.0f;	//图像的中心
	const float centerY = imgHeight / 2.0f;			
	
	// 1. 绘制上半椭圆（蓝色）
	setfillcolor(e->top_color);
	ege_fillpie(
		centerX - e->a,  // x
		centerY - e->b,  // y
		e->a * 2,        // 宽度
		e->b * 2,        // 高度
		180,            // 起始角度（度）
		180,            // 扫描角度（度）
		pimg
		);
	
	// 2. 绘制下半椭圆（棕色）
	setfillcolor(e->bottom_color);
	ege_fillpie(
		centerX - e->a,  // x
		centerY - e->b,  // y
		e->a * 2,        // 宽度
		e->b * 2,        // 高度
		0,               // 起始角度（度）
		180,             // 扫描角度（度）
		pimg
		);
	
	setlinestyle(SOLID_LINE, 0, 4);
	ege_line(centerX - e->a, centerY, centerX + e->a, centerY);
	
	// 绘制俯仰角指示
	setlinestyle(SOLID_LINE, 0, 2);
	
	// 上方横线
	ege_line(centerX-35, centerY-30, centerX+35, centerY-30);
	ege_outtextxy(centerX-53, centerY-45, "10");
	ege_outtextxy(centerX+40, centerY-45, "10");
	ege_line(centerX-50, centerY-60, centerX+50, centerY-60);
	ege_outtextxy(centerX-68, centerY-70, "20");
	ege_outtextxy(centerX+55, centerY-70, "20");
	
	// 中间短线
	setlinestyle(SOLID_LINE, 0, 1);
	ege_line(centerX-15, centerY-15, centerX+15, centerY-15);
	ege_line(centerX-15, centerY-45, centerX+15, centerY-45);
	ege_line(centerX-15, centerY-75, centerX+15, centerY-75);
	
	// 下方横线
	setcolor(WHITE);
	setlinestyle(SOLID_LINE, 0, 2);
	ege_line(centerX-35, centerY+30, centerX+35, centerY+30);
	ege_outtextxy(centerX-53, centerY+15, "10");
	ege_outtextxy(centerX+40, centerY+15, "10");
	ege_line(centerX-50, centerY+60, centerX+50, centerY+60);
	ege_outtextxy(centerX-68, centerY+50, "20");
	ege_outtextxy(centerX+55, centerY+50, "20");
	
	// 下方短线
	setlinestyle(SOLID_LINE, 0, 1);
	ege_line(centerX-15, centerY+15, centerX+15, centerY+15);
	ege_line(centerX-15, centerY+45, centerX+15, centerY+45);
	
	//绘制小螺丝
	setfillcolor(EGERGB(65,65,65));
	ege_fillellipse(centerX-155,centerY+5,14,14);
	setcolor(BLACK);
	setlinestyle(SOLID_LINE,0,2);
	ege_line(centerX-151,centerY+15,centerX-145,centerY+9);
	
	setfillcolor(EGERGB(65,65,65));
	ege_fillellipse(centerX-155,centerY-19,14,14);
	setcolor(BLACK);
	setlinestyle(SOLID_LINE,0,2);
	ege_line(centerX-151,centerY-9,centerX-145,centerY-15);
	
	setfillcolor(EGERGB(65,65,65));
	ege_fillellipse(centerX+141,centerY+5,14,14);
	setcolor(BLACK);
	setlinestyle(SOLID_LINE,0,2);
	ege_line(centerX+151,centerY+9,centerX+145,centerY+15);
	
	setfillcolor(EGERGB(65,65,65));
	ege_fillellipse(centerX+141,centerY-19,14,14);
	setcolor(BLACK);
	setlinestyle(SOLID_LINE,0,2);
	ege_line(centerX+151,centerY-15,centerX+145,centerY-9);
	
	// 恢复主画布为绘图目标
	settarget(NULL);
	
// 5. 旋转绘制组合图像（中心旋转）
	putimage_rotatezoom(
		NULL,           // 目标：屏幕
		pimg,      // 源图像
		(int)e->x, (int)e->y,      // 屏幕中心位置
		0.5f, 0.5f,     // 旋转中心比例（图像中心）
		e->angle,          // 旋转角度
		1.0f,          // 缩放比例
		true,          // 使用透明
		-1,            // 不设置额外透明度
		true           // 平滑旋转
		);	
}

void drawScale(float cx, float cy, float radius, float angle)
{
	// 创建临时图像（大小要能容纳整个仪表）
	const int imgWidth = 800;
	const int imgHeight = 600;
	PIMAGE pimg = newimage(imgWidth, imgHeight);
	
	// 设置临时图像为当前绘图目标
	settarget(pimg);    
	// 清空临时图像（透明背景）
	setbkcolor(TRANSPARENT);
	cleardevice();
	
	// 临时图像的中心（所有绘图都基于这个中心）
	const float centerX = imgWidth / 2.0f;
	const float centerY = imgHeight / 2.0f;
	
	// 绘制圆环（基于临时图像中心）
	float outerRadius = radius * 0.95;
	float innerRadius = radius * 0.8f;
	
	for (int iy = 0; iy < imgHeight; iy++) 
	{
		for (int ix = 0; ix < imgWidth; ix++) 
		{
			float dx = ix - centerX;
			float dy = iy - centerY;
			float dist = sqrt(dx*dx + dy*dy);
			if (dist <= innerRadius || dist > outerRadius) continue;
			
			color_t currentColor;
			if (iy <= centerY) // 上半部分：蓝色
				currentColor = EGERGB(63, 83, 130);
			else               // 下半部分:棕色
				currentColor = EGERGB(85, 78, 54);
			
			putpixel(ix, iy, currentColor);
		}
	}
	
	// 绘制刻度（不再预先应用旋转角度）
	float angleRad = 0; // 在临时图像中绘制时不预先旋转
	
	// 主刻度（每30度一个）
	for(int i = 0; i < 7; ++i)
	{
		float currentAngle = angleRad + i * PI / 6.0f; // 30度一个刻度
		if(sin(currentAngle) >= -0.4147f)
		{
			int x1 = centerX + (radius - 40) * cos(currentAngle);
			int y1 = centerY - (radius - 40) * sin(currentAngle);
			int x2 = centerX + (radius - 10) * cos(currentAngle);
			int y2 = centerY - (radius - 10) * sin(currentAngle);
			
			setcolor(WHITE);
			setlinestyle(SOLID_LINE, 0, 5);
			ege_line(x1, y1, x2, y2);            
		}
	}
	
	// 次刻度（每10度一个）
	float startAngle = angleRad + (70 * PI / 180.0f);
	for(int i = 0; i < 5; ++i)
	{
		float currentAngle = startAngle + i * PI / 18.0f; // 10度一个刻度
		if(sin(currentAngle) >= -0.4147f)
		{
			int x1 = centerX + (radius - 40) * cos(currentAngle);
			int y1 = centerY - (radius - 40) * sin(currentAngle);
			int x2 = centerX + (radius - 15) * cos(currentAngle);
			int y2 = centerY - (radius - 15) * sin(currentAngle);
			
			setcolor(WHITE);
			setlinestyle(SOLID_LINE, 0, 3);
			ege_line(x1, y1, x2, y2);            
		}                    
	}
	
	// 恢复主画布
	settarget(NULL);
	
	// 旋转绘制整个临时图像（包括圆环和刻度）
	putimage_rotatezoom(
		NULL,           // 目标：屏幕
		pimg,           // 源图像
		(int)cx, (int)cy, // 屏幕中心位置
		0.5f, 0.5f,     // 旋转中心比例（图像中心）
		angle * PI / 180.0f, // 旋转角度（从度转换为弧度）
		1.0f,           // 缩放比例
		true,           // 使用透明
		-1,             // 不设置额外透明度
		true            // 平滑旋转
		);
	
	// 释放临时图像
	delimage(pimg);
}


//画外部框
void drawDashboardSurround(float x, float y, float r)
{
	//画灰色底座矩形
	setfillcolor(EGERGB(74,74,74));
	ege_fillrect(x-r-30,y-r-30,2*r+60,2*r+60);
	//画外围白色的类矩形
	setlinestyle(SOLID_LINE, 0, 6);
	setcolor(WHITE);
	ege_arc(x-r-70,y-r+30,2*r+150,2*r-20,31.0,119.0);
	ege_arc(x-r-70,y-r-10,2*r+150,2*r-20,211,118.0);
	ege_line(x-r-3,y-r+49,x-r-3,y+r-52);
	ege_line(x+r+9,y-r+48,x+r+9,y+r-51);
}

// 绘制仪表盘指示函数
void drawPointer(int centerX, int centerY, int radius) 
{
	int width = 20;  // 指针宽度	
	// 指针头部，绘制一个三角形
	setcolor(WHITE);
	setfillcolor(WHITE);
	int Points[] = {centerX, centerY- radius + 42, centerX - width / 2, centerY - radius +57, centerX + width / 2, centerY - radius + 57, centerX, centerY - radius + 42};
	fillpoly(4, Points); 
}

void drawDetails(float x, float y, float radius)
{
	//画过侧边的基准线
	setlinestyle(SOLID_LINE,0,3);
	setcolor(EGERGB(240,150,50));
	ege_line(x-radius+95,y-70,x-radius+95,y+70);
	
	//画下半部分棕黑色分界线
	setcolor(EGERGB(74,74,74));	
	setlinestyle(SOLID_LINE,0,2);
//	ege_arc(x-20-radius/2,y+75,radius+40,70,180,180);
	ege_line(x-20-radius/2,y+110,x+30-radius/2,y+83);
	ege_line(x+20+radius/2,y+110,x-30.5+radius/2,y+82);
	ege_arc(x-70,y+70,140,30,180,180);
	ege_line(x-60,y+140,x+60,y+140);
	ege_line(x-radius+20,y+80,x-60,y+140);
	ege_line(x+radius-20,y+80,x+60,y+140);
//	填充下部分扇形黑色
	setfillcolor(EGERGB(40,40,40));
	floodfill((int)x,(int)(y+105),EGERGB(74,74,74));
	setfillcolor(EGERGB(75,75,75));
	floodfill((int)x,(int)(y+145),EGERGB(74,74,74));
	
	//绘制底部的英文
	setcolor(WHITE);
	LOGFONTW lf;	// 定义 LOGFONTW 结构体变量
	ZeroMemory(&lf, sizeof(LOGFONTW));	// 清空结构体	
	// 设置字体属性
	lf.lfHeight = 25;           // 字体高度为 25 像素
	lf.lfWeight = FW_BOLD;      // 字体粗细为粗体
	lf.lfItalic = TRUE; 		// 非斜体
	lf.lfUnderline = FALSE;     // 无下划线
	lf.lfStrikeOut = FALSE;     // 无删除线
	lstrcpyW(lf.lfFaceName, L"微软雅黑"); // 字体名称为黑体	
	setfont(&lf);	// 设置字体
	ege_outtextxy((int)(x-60),(int)(y+radius-50),"BENDIXIKING");
	
	//绘制指针
	drawPointer(x, y, radius);
}

void drawDetailCircle(float x, float y, float radius)
{
	// 绘制仪表盘外圆
	setcolor(EGERGB(74, 74, 74));
	setlinestyle(SOLID_LINE,0,2);
	ege_arc(x - radius + 5, y - radius + 5, 390.0, 390.0, 0, 24.5);
	ege_arc(x - radius + 5, y - radius + 5, 390.0, 390.0, 155.5, 24.5);
	ege_arc(x - radius + 5, y - radius + 5, 390.0, 390.0, 180, 180);
	ege_arc(x - radius + 5, y - radius + 5, 390.0, 390.0, 24.5, 131);
	setcolor(WHITE);
	setlinestyle(SOLID_LINE,0,1);
	ege_arc(x - radius + 7, y - radius + 7, 386.0, 386.0, 0, 24.5);
	ege_arc(x - radius + 7, y - radius + 7, 386.0, 386.0, 155.5, 24.5);
	ege_arc(x - radius + 7, y - radius + 7, 386.0, 386.0, 180, 180);
}

//画代表飞机的小模型
void drawModePlane(float x,float y, float r)
{
	//画橙色的水平线和小圆点
	setlinestyle(SOLID_LINE,0,4);
	setcolor(EGERGB(240,150,50));
	ege_line(x-90, y, x-30, y);
	ege_line(x+30, y, x+90, y);
	setfillcolor(EGERGB(240,150,50));
	ege_fillellipse(x-4, y-4, 8.0, 8.0);
	//画杆子
	setlinestyle(SOLID_LINE,0,8);
	setcolor(EGERGB(100,100,60));
	ege_line(x,y+70,x,y+20);
	setlinestyle(SOLID_LINE,0,3);
	ege_line(x,y+20,x,y+5);
	ege_arc(x-30,y-20,60.0,40.0,0,180.0);
	
}

// 绘制仪表盘
void drawDashboard(float x, float y, float radius, float angle) 
{
	drawDetailCircle(x,y,radius); 
	//绘制一些细节
	drawDetails(x,y,radius);
	//绘制反映飞机俯仰角的小模型
	drawModePlane(x,y,radius);	
}

int main() 
{
	// 初始化图形窗口
	initgraph(800, 600);
	ege_enable_aa(true);
	//仪表背景色
	setrendermode(RENDER_MANUAL);
	setbkcolor(EGERGB(190,190,190));
	cleardevice();
	float centerX = 400;
	float centerY = 300;
	float radius = 200;
	float angle = 0;
	MyEllipse ellipse;
	initEllipse(&ellipse, centerX, centerY, radius * 0.84, radius * 0.58, EGERGB(63,83,130), EGERGB(85, 78, 54));
	const float move_step = 3.0f;
	const float rotate_step = 0.03f;
	// 绘制仪表盘
	while (!GetAsyncKeyState(VK_ESCAPE)) 
	{
		// 清屏
		cleardevice();
		//绘制外部背景
		drawDashboardSurround(centerX,centerY,radius);
		// 重新绘制仪表盘
		draw_gradient_circle(centerX,centerY,radius);

		if (GetAsyncKeyState(VK_LEFT) & 0x8000) ellipse.x -= move_step;
		if (GetAsyncKeyState(VK_RIGHT) & 0x8000) ellipse.x += move_step;
		if (GetAsyncKeyState(VK_UP) & 0x8000) ellipse.y -= move_step;
		if (GetAsyncKeyState(VK_DOWN) & 0x8000) ellipse.y += move_step;
		if (GetAsyncKeyState('A') & 0x8000) ellipse.angle -= rotate_step;
		if (GetAsyncKeyState('D') & 0x8000) ellipse.angle += rotate_step;
		
		// 角度归一化
		if (ellipse.angle < 0) ellipse.angle += 2 * PI;
		if (ellipse.angle > 2 * PI) ellipse.angle -= 2 * PI;		
		// 绘制双色椭圆
		drawEllipse(&ellipse);
		// 绘制刻度
		drawScale(centerX, centerY, radius, angle);
		//
		drawDashboard(centerX, centerY, radius, angle);
		//更新角度
		angle += 1;
		// 延迟一段时间，控制转动速度
		delay_ms(50);
	}
	getch();
	closegraph();
	return 0;
}
